{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "_cell_guid": "b1076dfc-b9ad-4769-8c92-a6c4dae69d19",
    "_uuid": "8f2839f25d086af736a60e9eeb907d3b93b6e0e5",
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:43.944795Z",
     "iopub.status.busy": "2023-11-02T08:54:43.944448Z",
     "iopub.status.idle": "2023-11-02T08:54:44.286383Z",
     "shell.execute_reply": "2023-11-02T08:54:44.285504Z",
     "shell.execute_reply.started": "2023-11-02T08:54:43.944766Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import gc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:44.288284Z",
     "iopub.status.busy": "2023-11-02T08:54:44.287949Z",
     "iopub.status.idle": "2023-11-02T08:54:47.476133Z",
     "shell.execute_reply": "2023-11-02T08:54:47.475150Z",
     "shell.execute_reply.started": "2023-11-02T08:54:44.288250Z"
    }
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "\n",
    "from torch.optim import AdamW\n",
    "from torch.optim.lr_scheduler import StepLR\n",
    "from torch.utils.data import Dataset, DataLoader\n",
    "from torch.nn.utils import clip_grad_norm_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:47.478557Z",
     "iopub.status.busy": "2023-11-02T08:54:47.477577Z",
     "iopub.status.idle": "2023-11-02T08:54:56.753915Z",
     "shell.execute_reply": "2023-11-02T08:54:56.753109Z",
     "shell.execute_reply.started": "2023-11-02T08:54:47.478515Z"
    }
   },
   "outputs": [],
   "source": [
    "import transformers\n",
    "from transformers import GPT2LMHeadModel, GPT2Tokenizer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:56.756455Z",
     "iopub.status.busy": "2023-11-02T08:54:56.756180Z",
     "iopub.status.idle": "2023-11-02T08:54:57.110892Z",
     "shell.execute_reply": "2023-11-02T08:54:57.110025Z",
     "shell.execute_reply.started": "2023-11-02T08:54:56.756432Z"
    }
   },
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.metrics import accuracy_score\n",
    "from sklearn.metrics import f1_score"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:57.112455Z",
     "iopub.status.busy": "2023-11-02T08:54:57.112166Z",
     "iopub.status.idle": "2023-11-02T08:54:57.117636Z",
     "shell.execute_reply": "2023-11-02T08:54:57.116657Z",
     "shell.execute_reply.started": "2023-11-02T08:54:57.112430Z"
    }
   },
   "outputs": [],
   "source": [
    "def free_memory():\n",
    "    gc.collect()\n",
    "    torch.cuda.empty_cache()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:57.119337Z",
     "iopub.status.busy": "2023-11-02T08:54:57.118956Z",
     "iopub.status.idle": "2023-11-02T08:54:57.823743Z",
     "shell.execute_reply": "2023-11-02T08:54:57.822686Z",
     "shell.execute_reply.started": "2023-11-02T08:54:57.119304Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>review</th>\n",
       "      <th>sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>качество плохое пошив ужасный (горловина напер...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Товар отдали другому человеку, я не получила п...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Ужасная синтетика! Тонкая, ничего общего с пре...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>товар не пришел, продавец продлил защиту без м...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Кофточка голая синтетика, носить не возможно.</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Очень глубокие проймы</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Я недовольна заказом.Я вот одного не понимаю п...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>заказала размер s на от 64,об 94,начнем с того...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Заказ я сделала в июле. С тех пор посылка отсл...</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Ужасное качество товара!</td>\n",
       "      <td>negative</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                              review sentiment\n",
       "0  качество плохое пошив ужасный (горловина напер...  negative\n",
       "1  Товар отдали другому человеку, я не получила п...  negative\n",
       "2  Ужасная синтетика! Тонкая, ничего общего с пре...  negative\n",
       "3  товар не пришел, продавец продлил защиту без м...  negative\n",
       "4      Кофточка голая синтетика, носить не возможно.  negative\n",
       "5                              Очень глубокие проймы  negative\n",
       "6  Я недовольна заказом.Я вот одного не понимаю п...  negative\n",
       "7  заказала размер s на от 64,об 94,начнем с того...  negative\n",
       "8  Заказ я сделала в июле. С тех пор посылка отсл...  negative\n",
       "9                           Ужасное качество товара!  negative"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reviews = pd.read_csv('data/reviews.csv.zip', sep='\\t')\n",
    "reviews.drop_duplicates(subset=['review'], inplace=True)\n",
    "reviews.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:57.825280Z",
     "iopub.status.busy": "2023-11-02T08:54:57.824968Z",
     "iopub.status.idle": "2023-11-02T08:54:58.073873Z",
     "shell.execute_reply": "2023-11-02T08:54:58.072769Z",
     "shell.execute_reply.started": "2023-11-02T08:54:57.825252Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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d+zYUQEBAerZs6ckacSIERo4cKBeeuklxcTEqFWrVpKk3/3ud+rSpYvq1q2r6OhoDR06VCdOnPDvgQFusZ49eyolJUUpKSmKiIhQo0aN9MILL9jfdn769Gk99dRTql+/vsLDw9WvXz8dPHjQXv8f//iHBgwYoPr166t27dq6++67tXr1akm+l7rWr1+vkSNH6uzZswoICFBAQIA95i+/1DV06FANHjzYp48lJSVq1KiR3nvvPUnffTtDRkaG4uLiFBYWpvbt2+uPf/xjhffdiOAjSYsXL1bt2rW1ZcsWzZ49WzNnzpTH45EkPf744zpx4oQ+/vhj5ebmqlOnTurdu7dOnTolSVqyZIleeuklvfLKK8rNzVWzZs309ttv+7R/7tw5DR8+XJs2bdLnn3+uO++8U/3799e5c+ckfReMJGnRokU6fvy4PX253r17q169evrTn/5kzystLdWyZcs0bNgwSd+98fft21eDBg3S7t27tWzZMm3atEkpKSn+P2hAFbiZsVhYWKj+/fsrOztbO3fuVN++fTVgwAAdPXr0hre/detWSdInn3yi48eP689//rO9LDs7WwcOHJDH49HKlSslfffmO2vWLO3atUsrVqzQkSNHNGLECD8dDaD6LF68WLVq1dLWrVs1b948vfbaa3rnnXckffeHwPbt2/WXv/xFOTk5sixL/fv3V0lJiSQpOTlZRUVF2rhxo/bs2aNXXnnlqlcvevTooblz58rpdOr48eM6fvy4Jk6ceEXdsGHD9NFHH6mwsNCet3btWl24cEGPPvqoJCkjI0PvvfeeFi5cqH379mnChAn6+c9/rg0bNlRsxy0DPPTQQ9b999/vM+/ee++1pkyZYn366aeW0+m0Ll686LP8jjvusH79619blmVZ3bp1s5KTk32W33fffVb79u2vuc3S0lKrbt261kcffWTPk2R98MEHPnXTp0/3aee5556zevXqZU+vXbvWcjgc1unTpy3LsqxRo0ZZTz/9tE8bn376qRUYGGh9++231+wP8GNws2Pxau6++27rzTfftKevNs4iIiKsRYsWWZZlWYcPH7YkWTt37vSpGT58uBUVFWUVFRVddx+2bdtmSbLOnTtnWZZl/fWvf7Uk2WMUuB089NBDVps2bayysjJ73pQpU6w2bdpYf/vb3yxJ1meffWYv++abb6ywsDDr/ffftyzLstq2bWulp6dfte3vj4lFixZZERERV9Q1b97cev311y3LsqySkhKrUaNG1nvvvWcvf+KJJ6zBgwdblmVZFy9etMLDw63Nmzf7tDFq1CjriSeeqNC+G3PGp127dj7TTZo00YkTJ7Rr1y4VFhaqYcOG9v02derU0eHDh3Xo0CFJ0oEDB9S1a1ef9b8/nZ+frzFjxujOO+9URESEnE6nCgsLK/SXqPRd6l2/fr2OHTsm6buzTUlJSfaNYbt27VJmZqZPX91ut8rKynT48OEKbQuoDjczFgsLCzVx4kS1adNG9erVU506dfTll19WeJxdS9u2ba+4ryc3N1cDBgxQs2bNVLduXT300EOS5LdtAtWle/fuCggIsKddLpcOHjyoL774QrVq1VK3bt3sZQ0bNlSrVq305ZdfSpKeffZZvfjii7rvvvs0ffp07d69+6b6UqtWLf3Hf/yHlixZIkk6f/68PvzwQ/tqx1dffaULFy6oT58+Pu8P7733nv3+cMPbuqme3kaCg4N9pgMCAlRWVqbCwkI1adJE69evv2Kdq92Ffi3Dhw/XyZMnNW/ePDVv3lwOh0Mul0vFxcUV6ue9996rO+64Q3/4wx80btw4ffDBB/a9CdJ3b/z/+Z//qWefffaKdZs1a1ahbQHV4WbG4sSJE+XxePTqq6+qZcuWCgsL089+9jOfcRYQEGDfp1Cu/PT8D6ldu7bP9Pnz5+V2u+V2u7VkyRI1btxYR48eldvtrvDYBmqS0aNHy+12a9WqVcrKylJGRobmzJmjZ555ptJtDhs2TA899JBOnDghj8ejsLAw9e3bV5LsS2CrVq3ST37yE5/1KvpdYMYEn2vp1KmTvF6vatWqZd9w/H2tWrXStm3b9NRTT9nzvn+Pzmeffaa33npL/fv3lyT985//1DfffONTExwcrNLS0h/s07Bhw7RkyRI1bdpUgYGBSkpK8unvF198oZYtW97oLgK3hRsZi5999plGjBhhX/MvLCzUkSNHfGoaN26s48eP29MHDx7UhQsX7OnyMzo3Mhb379+vkydP6uWXX1ZsbKwkafv27RXZLeBHa8uWLT7T5fenxsfH69KlS9qyZYt69OghSTp58qQOHDig+Ph4uz42NlZjx47V2LFjlZaWpv/5n/+5avAJCQm5ofHWo0cPxcbGatmyZfr444/1+OOP238oxcfHy+Fw6OjRo/ZZ18oy5lLXtSQkJMjlcmngwIHKysrSkSNHtHnzZv33f/+3/Qb3zDPP6Le//a0WL16sgwcP6sUXX9Tu3bt9ThHeeeed+t3vfqcvv/xSW7Zs0bBhwxQWFuazrRYtWig7O1ter1enT5++Zp+GDRumHTt26KWXXtLPfvYznzQ7ZcoUbd68WSkpKcrLy9PBgwf14YcfcnMzbns3MhbvvPNO/fnPf1ZeXp527dqloUOHqqyszKedXr16af78+dq5c6e2b9+usWPH+pxlioyMVFhYmNasWaP8/HydPXv2mn1q1qyZQkJC9Oabb+rvf/+7/vKXv2jWrFlVcwCAW+zo0aNKTU3VgQMH9Pvf/15vvvmmnnvuOd1555165JFHNGbMGG3atEm7du3Sz3/+c/3kJz/RI488IkkaP3681q5dq8OHD2vHjh3661//qjZt2lx1Oy1atFBhYaGys7P1zTff+Pwh8n1Dhw7VwoUL5fF47MtcklS3bl1NnDhREyZM0OLFi3Xo0CHt2LFDb775phYvXlyh/TY++AQEBGj16tV68MEHNXLkSN11110aMmSI/vGPfygqKkrSd0EkLS1NEydOVKdOnXT48GGNGDFCoaGhdju//e1vdfr0aXXq1ElPPvmknn32WUVGRvpsa86cOfJ4PIqNjVXHjh2v2aeWLVuqa9eu2r17t89/vPTd/REbNmzQ3/72Nz3wwAPq2LGjpk2bppiYGD8eFeDWu5Gx+Nprr6l+/frq0aOHBgwYILfbrU6dOvm0M2fOHMXGxuqBBx7Q0KFDNXHiRIWHh9vLa9WqpTfeeEO//vWvFRMTY7+RX03jxo2VmZmp5cuXKz4+Xi+//LJeffXVqjkAwC321FNP6dtvv1XXrl2VnJys5557zv5AwUWLFqlz58766U9/KpfLJcuytHr1avuPiNLSUiUnJ6tNmzbq27ev7rrrLr311ltX3U6PHj00duxYDR48WI0bN9bs2bOv2adhw4bpiy++0E9+8hPdd999PstmzZqlF154QRkZGfZ2V61aZX9ExY0KsL5/MRw3pE+fPoqOjtbvfve76u4KAAAV0rNnT3Xo0KFavjKiuhl/j8+NuHDhghYuXCi3262goCD9/ve/1yeffGJ/9ggAALg9EHxuQPkp+JdeekkXL15Uq1at9Kc//UkJCQnV3TUAAFABXOoCAADGMP7mZgAAYA6CDwAAMAbBBwAAGIPgAwAAjEHwAQAAxiD4AAAAYxB8AACAMQg+AADAGAQfAABgjP8HaHMWNKrk8iUAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "reviews.sentiment.hist()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:58.075921Z",
     "iopub.status.busy": "2023-11-02T08:54:58.075543Z",
     "iopub.status.idle": "2023-11-02T08:54:58.080739Z",
     "shell.execute_reply": "2023-11-02T08:54:58.079764Z",
     "shell.execute_reply.started": "2023-11-02T08:54:58.075886Z"
    }
   },
   "outputs": [],
   "source": [
    "sentiment_map = {\n",
    "    'negative': 0,\n",
    "    'neautral': 1,\n",
    "    'positive': 2\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:58.086071Z",
     "iopub.status.busy": "2023-11-02T08:54:58.085457Z",
     "iopub.status.idle": "2023-11-02T08:54:58.156911Z",
     "shell.execute_reply": "2023-11-02T08:54:58.156004Z",
     "shell.execute_reply.started": "2023-11-02T08:54:58.086037Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>review</th>\n",
       "      <th>sentiment</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>качество плохое пошив ужасный (горловина напер...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>Товар отдали другому человеку, я не получила п...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>Ужасная синтетика! Тонкая, ничего общего с пре...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>товар не пришел, продавец продлил защиту без м...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>Кофточка голая синтетика, носить не возможно.</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>Очень глубокие проймы</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>Я недовольна заказом.Я вот одного не понимаю п...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>заказала размер s на от 64,об 94,начнем с того...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>Заказ я сделала в июле. С тех пор посылка отсл...</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>Ужасное качество товара!</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                              review  sentiment\n",
       "0  качество плохое пошив ужасный (горловина напер...          0\n",
       "1  Товар отдали другому человеку, я не получила п...          0\n",
       "2  Ужасная синтетика! Тонкая, ничего общего с пре...          0\n",
       "3  товар не пришел, продавец продлил защиту без м...          0\n",
       "4      Кофточка голая синтетика, носить не возможно.          0\n",
       "5                              Очень глубокие проймы          0\n",
       "6  Я недовольна заказом.Я вот одного не понимаю п...          0\n",
       "7  заказала размер s на от 64,об 94,начнем с того...          0\n",
       "8  Заказ я сделала в июле. С тех пор посылка отсл...          0\n",
       "9                           Ужасное качество товара!          0"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reviews.sentiment = reviews.sentiment.apply(lambda x: sentiment_map[x])\n",
    "reviews.head(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:58.158680Z",
     "iopub.status.busy": "2023-11-02T08:54:58.158192Z",
     "iopub.status.idle": "2023-11-02T08:54:58.170682Z",
     "shell.execute_reply": "2023-11-02T08:54:58.169762Z",
     "shell.execute_reply.started": "2023-11-02T08:54:58.158641Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(13098, 2)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reviews_sample = reviews.sample(frac=0.15, replace=True, random_state=42)\n",
    "reviews_sample.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:58.172037Z",
     "iopub.status.busy": "2023-11-02T08:54:58.171753Z",
     "iopub.status.idle": "2023-11-02T08:54:58.425538Z",
     "shell.execute_reply": "2023-11-02T08:54:58.424480Z",
     "shell.execute_reply.started": "2023-11-02T08:54:58.172015Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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qqpSVlaWCgoK9L//+78BdXfffbc+++wz++uVV165Hu1cVrA9Sl/+75GXzv/Pf/5zwH6T1/C1114L6O3o0aOKi4vTP//zPwfURcoanj17VsOHD1dZWVm76uvq6lRUVKTx48erpqZGJSUlmj17dsCTfEceE+ESbH/79u3ThAkTtGPHDlVXV2v8+PG65557dOTIkYC6wYMHB6zfO++8E47pt0uwPfodP348oIe0tDR7n8lruGbNmoC+Pv30U6WmprY5ByNlDffu3avi4mIdOHBAbrdbXq9XBQUFOnv2yr9gMiKeC60ubsyYMVZxcbF9u7W11crMzLSWL19+2frvf//7VlFRUcC2vLw861//9V8ty7Isn89nZWRkWD/5yU/s/adOnbIcDof1yiuvhKGDqwu2v6+6ePGi1bNnT2vDhg32tpkzZ1qTJk0K9VQ7LNge169fbyUnJ19xvGhbw9WrV1s9e/a0zpw5Y2+LtDX0k2Rt3br1qjXz58+3Bg8eHLBt6tSpVmFhoX37695n4dKe/i4nNzfXWrJkiX170aJF1vDhw0M3sRBqT49vv/22Jcn629/+dsWaaFrDrVu3WjExMdaf/vQne1skr2FjY6Mlydq7d+8VayLhubBLX4FpaWlRdXW18vPz7W2xsbHKz89XVVXVZY+pqqoKqJekwsJCu76urk719fUBNcnJycrLy7vimOHSkf6+6ty5c/J6vUpNTQ3YXllZqbS0NA0YMEBz5szR559/HtK5t1dHezxz5oyys7OVlZWlSZMm6dixY/a+aFvDdevWadq0aerRo0fA9khZw2Bd6xwMxX0WSXw+n5qbm9ucgx999JEyMzN18803a/r06Tpx4kQnzbDjRowYoT59+mjChAl699137e3Rtobr1q1Tfn6+srOzA7ZH6hqePn1akto85i4VCc+FXTrA/PWvf1Vra2ub/903PT29zWuxfvX19Vet9/8ZzJjh0pH+vurxxx9XZmZmwIPw7rvv1q9//Wvt3r1bTz/9tPbu3auJEyeqtbU1pPNvj470OGDAAL300kt644039Jvf/EY+n0+33nqr/vKXv0iKrjU8dOiQjh49qtmzZwdsj6Q1DNaVzsGmpiadP38+JI/7SPLMM8/ozJkz+v73v29vy8vLU3l5uXbu3KkXXnhBdXV1uu2229Tc3NyJM22/Pn36aO3atfrd736n3/3ud8rKytK4ceN0+PBhSaH52RUpTp48qd///vdtzsFIXUOfz6eSkhJ95zvf0ZAhQ65YFwnPhRH7qwTQ+VasWKFNmzapsrIy4E2u06ZNs/8+dOhQDRs2TN/85jdVWVmpu+66qzOmGhSXyxXwS0FvvfVWDRo0SL/4xS+0bNmyTpxZ6K1bt05Dhw7VmDFjArabvoZdxcaNG7VkyRK98cYbAe8PmThxov33YcOGKS8vT9nZ2dq8ebNmzZrVGVMNyoABAzRgwAD79q233qpPPvlEq1ev1n/+53924sxCb8OGDUpJSdHkyZMDtkfqGhYXF+vo0aOd+p6q9urSV2B69+6tuLg4NTQ0BGxvaGhQRkbGZY/JyMi4ar3/z2DGDJeO9Of3zDPPaMWKFaqoqNCwYcOuWnvzzTerd+/e+vjjj7/2nIP1dXr0i4+P1y233GLPP1rW8OzZs9q0aVO7fhh25hoG60rnoNPpVPfu3UPymIgEmzZt0uzZs7V58+Y2l+q/KiUlRd/61reMWL8rGTNmjD3/aFlDy7L00ksvacaMGUpISLhqbSSs4dy5c7Vt2za9/fbb6tu371VrI+G5sEsHmISEBI0aNUq7d++2t/l8Pu3evTvgX+iXcrlcAfWS5Ha77fqcnBxlZGQE1DQ1NengwYNXHDNcOtKf9OU7x5ctW6adO3dq9OjR1/w+f/nLX/T555+rT58+IZl3MDra46VaW1tVW1trzz8a1lD68iOOHo9H99133zW/T2euYbCudQ6G4jHR2V555RU98MADeuWVVwI+/n4lZ86c0SeffGLE+l1JTU2NPf9oWEPpy0/3fPzxx+36R0RnrqFlWZo7d662bt2qPXv2KCcn55rHRMRzYUjeCmywTZs2WQ6HwyovL7c++OAD6+GHH7ZSUlKs+vp6y7Isa8aMGdYTTzxh17/77rtWt27drGeeecb68MMPrUWLFlnx8fFWbW2tXbNixQorJSXFeuONN6w//OEP1qRJk6ycnBzr/PnzEd/fihUrrISEBOu3v/2t9dlnn9lfzc3NlmVZVnNzs/Xv//7vVlVVlVVXV2e99dZb1siRI62///u/ty5cuHDd++tIj0uWLLF27dplffLJJ1Z1dbU1bdo0KzEx0Tp27JhdY/Ia+n33u9+1pk6d2mZ7pK1hc3OzdeTIEevIkSOWJOvZZ5+1jhw5Yv35z3+2LMuynnjiCWvGjBl2/f/8z/9YSUlJ1mOPPWZ9+OGHVllZmRUXF2ft3LnTrrnWfRbJ/b388stWt27drLKysoBz8NSpU3bNv/3bv1mVlZVWXV2d9e6771r5+flW7969rcbGxuven2UF3+Pq1aut119/3froo4+s2tpa60c/+pEVGxtrvfXWW3aNyWvod99991l5eXmXHTOS1nDOnDlWcnKyVVlZGfCYO3funF0Tic+FXT7AWJZl/exnP7P69etnJSQkWGPGjLEOHDhg77vjjjusmTNnBtRv3rzZ+ta3vmUlJCRYgwcPtrZv3x6w3+fzWU899ZSVnp5uORwO66677rKOHz9+PVq5rGD6y87OtiS1+Vq0aJFlWZZ17tw5q6CgwPrGN75hxcfHW9nZ2dZDDz3UKT9ULhVMjyUlJXZtenq69b3vfc86fPhwwHgmr6FlWdYf//hHS5JVUVHRZqxIW0P/R2q/+uXvaebMmdYdd9zR5pgRI0ZYCQkJ1s0332ytX7++zbhXu8+up2D7u+OOO65ab1lffmy8T58+VkJCgvV3f/d31tSpU62PP/74+jZ2iWB7fPrpp61vfvObVmJiopWammqNGzfO2rNnT5txTV1Dy/ryI8Pdu3e3fvnLX152zEhaw8v1JingvIrE58KY/z95AAAAY3Tp98AAAAAzEWAAAIBxCDAAAMA4BBgAAGAcAgwAADAOAQYAABiHAAMAAIxDgAEAAMYhwAAAAOMQYAAAgHEIMAAAwDgEGAAAYJz/B+ZXzRGan5J0AAAAAElFTkSuQmCC",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "reviews_sample.sentiment.hist()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:58.427171Z",
     "iopub.status.busy": "2023-11-02T08:54:58.426825Z",
     "iopub.status.idle": "2023-11-02T08:54:58.457295Z",
     "shell.execute_reply": "2023-11-02T08:54:58.456336Z",
     "shell.execute_reply.started": "2023-11-02T08:54:58.427136Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'cuda'"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "device = ('cuda' if torch.cuda.is_available() else 'cpu')\n",
    "device"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:58.458891Z",
     "iopub.status.busy": "2023-11-02T08:54:58.458562Z",
     "iopub.status.idle": "2023-11-02T08:54:58.465802Z",
     "shell.execute_reply": "2023-11-02T08:54:58.464886Z",
     "shell.execute_reply.started": "2023-11-02T08:54:58.458860Z"
    }
   },
   "outputs": [],
   "source": [
    "pretrained_model_name_or_path = 'sberbank-ai/rugpt3medium_based_on_gpt2'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:54:58.467283Z",
     "iopub.status.busy": "2023-11-02T08:54:58.466957Z",
     "iopub.status.idle": "2023-11-02T08:57:25.026919Z",
     "shell.execute_reply": "2023-11-02T08:57:25.025884Z",
     "shell.execute_reply.started": "2023-11-02T08:54:58.467251Z"
    }
   },
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "93dc1de788d54c68bbc8c1d399843663",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)lve/main/config.json:   0%|          | 0.00/674 [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5b1d72dec05d4b909f76da23e0df260d",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading pytorch_model.bin:   0%|          | 0.00/1.73G [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "c5b66fa85cd04377976d3645caeb4bbc",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)olve/main/vocab.json:   0%|          | 0.00/1.61M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "8a7fa81bd76044398c4639c8d9b954bc",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "Downloading (…)olve/main/merges.txt:   0%|          | 0.00/1.27M [00:00<?, ?B/s]"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "gpt = GPT2LMHeadModel.from_pretrained(pretrained_model_name_or_path)\n",
    "tokenizer = GPT2Tokenizer.from_pretrained(pretrained_model_name_or_path)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:25.028424Z",
     "iopub.status.busy": "2023-11-02T08:57:25.028129Z",
     "iopub.status.idle": "2023-11-02T08:57:25.036498Z",
     "shell.execute_reply": "2023-11-02T08:57:25.035551Z",
     "shell.execute_reply.started": "2023-11-02T08:57:25.028400Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GPT2LMHeadModel(\n",
       "  (transformer): GPT2Model(\n",
       "    (wte): Embedding(50257, 1024)\n",
       "    (wpe): Embedding(2048, 1024)\n",
       "    (drop): Dropout(p=0.1, inplace=False)\n",
       "    (h): ModuleList(\n",
       "      (0-23): 24 x GPT2Block(\n",
       "        (ln_1): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n",
       "        (attn): GPT2Attention(\n",
       "          (c_attn): Conv1D()\n",
       "          (c_proj): Conv1D()\n",
       "          (attn_dropout): Dropout(p=0.1, inplace=False)\n",
       "          (resid_dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "        (ln_2): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n",
       "        (mlp): GPT2MLP(\n",
       "          (c_fc): Conv1D()\n",
       "          (c_proj): Conv1D()\n",
       "          (act): NewGELUActivation()\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "    )\n",
       "    (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n",
       "  )\n",
       "  (lm_head): Linear(in_features=1024, out_features=50257, bias=False)\n",
       ")"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:25.038017Z",
     "iopub.status.busy": "2023-11-02T08:57:25.037693Z",
     "iopub.status.idle": "2023-11-02T08:57:25.048408Z",
     "shell.execute_reply": "2023-11-02T08:57:25.047521Z",
     "shell.execute_reply.started": "2023-11-02T08:57:25.037985Z"
    }
   },
   "outputs": [],
   "source": [
    "for param in gpt.parameters():\n",
    "    param.requires_grad = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:25.049790Z",
     "iopub.status.busy": "2023-11-02T08:57:25.049516Z",
     "iopub.status.idle": "2023-11-02T08:57:25.061919Z",
     "shell.execute_reply": "2023-11-02T08:57:25.061006Z",
     "shell.execute_reply.started": "2023-11-02T08:57:25.049762Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "num_labels = reviews.sentiment.nunique()\n",
    "num_labels"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:25.063310Z",
     "iopub.status.busy": "2023-11-02T08:57:25.063046Z",
     "iopub.status.idle": "2023-11-02T08:57:29.958751Z",
     "shell.execute_reply": "2023-11-02T08:57:29.957747Z",
     "shell.execute_reply.started": "2023-11-02T08:57:25.063287Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GPT2LMHeadModel(\n",
       "  (transformer): GPT2Model(\n",
       "    (wte): Embedding(50257, 1024)\n",
       "    (wpe): Embedding(2048, 1024)\n",
       "    (drop): Dropout(p=0.1, inplace=False)\n",
       "    (h): ModuleList(\n",
       "      (0-23): 24 x GPT2Block(\n",
       "        (ln_1): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n",
       "        (attn): GPT2Attention(\n",
       "          (c_attn): Conv1D()\n",
       "          (c_proj): Conv1D()\n",
       "          (attn_dropout): Dropout(p=0.1, inplace=False)\n",
       "          (resid_dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "        (ln_2): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n",
       "        (mlp): GPT2MLP(\n",
       "          (c_fc): Conv1D()\n",
       "          (c_proj): Conv1D()\n",
       "          (act): NewGELUActivation()\n",
       "          (dropout): Dropout(p=0.1, inplace=False)\n",
       "        )\n",
       "      )\n",
       "    )\n",
       "    (ln_f): LayerNorm((1024,), eps=1e-05, elementwise_affine=True)\n",
       "  )\n",
       "  (lm_head): Linear(in_features=1024, out_features=3, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gpt.lm_head = nn.Linear(gpt.config.hidden_size, num_labels)\n",
    "gpt = gpt.to(device)\n",
    "gpt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:29.960773Z",
     "iopub.status.busy": "2023-11-02T08:57:29.960174Z",
     "iopub.status.idle": "2023-11-02T08:57:29.965285Z",
     "shell.execute_reply": "2023-11-02T08:57:29.964301Z",
     "shell.execute_reply.started": "2023-11-02T08:57:29.960732Z"
    }
   },
   "outputs": [],
   "source": [
    "X = reviews_sample.review\n",
    "y = reviews_sample.sentiment"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:29.967341Z",
     "iopub.status.busy": "2023-11-02T08:57:29.966637Z",
     "iopub.status.idle": "2023-11-02T08:57:29.978591Z",
     "shell.execute_reply": "2023-11-02T08:57:29.977743Z",
     "shell.execute_reply.started": "2023-11-02T08:57:29.967315Z"
    }
   },
   "outputs": [],
   "source": [
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:29.980640Z",
     "iopub.status.busy": "2023-11-02T08:57:29.980043Z",
     "iopub.status.idle": "2023-11-02T08:57:29.986251Z",
     "shell.execute_reply": "2023-11-02T08:57:29.985350Z",
     "shell.execute_reply.started": "2023-11-02T08:57:29.980575Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<pad>\n"
     ]
    }
   ],
   "source": [
    "tokenizer.pad_token_id = 0\n",
    "print(tokenizer.pad_token)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:29.987566Z",
     "iopub.status.busy": "2023-11-02T08:57:29.987311Z",
     "iopub.status.idle": "2023-11-02T08:57:29.995888Z",
     "shell.execute_reply": "2023-11-02T08:57:29.995001Z",
     "shell.execute_reply.started": "2023-11-02T08:57:29.987544Z"
    }
   },
   "outputs": [],
   "source": [
    "class SentimentAnalysisDataset(Dataset):\n",
    "    def __init__(self, X, y, tokenizer=None, num_labels=3):\n",
    "        self.X = tokenizer(X.tolist(), \n",
    "                           truncation=True, \n",
    "                           padding=True,\n",
    "                           return_tensors=\"pt\",\n",
    "                           max_length=2048).to(device)\n",
    "        self.y = torch.tensor(y.to_numpy(), dtype=torch.int64).to(device)\n",
    "    \n",
    "    def __len__(self):\n",
    "        return len(self.y)\n",
    "    \n",
    "    def __getitem__(self, idx):\n",
    "        return self.X.input_ids[idx], self.X.attention_mask[idx], self.y[idx]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:29.997763Z",
     "iopub.status.busy": "2023-11-02T08:57:29.996973Z",
     "iopub.status.idle": "2023-11-02T08:57:41.748390Z",
     "shell.execute_reply": "2023-11-02T08:57:41.747312Z",
     "shell.execute_reply.started": "2023-11-02T08:57:29.997736Z"
    }
   },
   "outputs": [],
   "source": [
    "train_dataset = SentimentAnalysisDataset(X_train, y_train, tokenizer)\n",
    "test_dataset = SentimentAnalysisDataset(X_test, y_test, tokenizer)\n",
    "\n",
    "free_memory()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:41.753282Z",
     "iopub.status.busy": "2023-11-02T08:57:41.752982Z",
     "iopub.status.idle": "2023-11-02T08:57:41.757571Z",
     "shell.execute_reply": "2023-11-02T08:57:41.756473Z",
     "shell.execute_reply.started": "2023-11-02T08:57:41.753251Z"
    }
   },
   "outputs": [],
   "source": [
    "batch_size = 32\n",
    "num_epochs = 15"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:41.759279Z",
     "iopub.status.busy": "2023-11-02T08:57:41.758907Z",
     "iopub.status.idle": "2023-11-02T08:57:41.767980Z",
     "shell.execute_reply": "2023-11-02T08:57:41.767000Z",
     "shell.execute_reply.started": "2023-11-02T08:57:41.759233Z"
    }
   },
   "outputs": [],
   "source": [
    "train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:41.769453Z",
     "iopub.status.busy": "2023-11-02T08:57:41.769099Z",
     "iopub.status.idle": "2023-11-02T08:57:41.778383Z",
     "shell.execute_reply": "2023-11-02T08:57:41.777422Z",
     "shell.execute_reply.started": "2023-11-02T08:57:41.769429Z"
    }
   },
   "outputs": [],
   "source": [
    "optimizer = AdamW(gpt.lm_head.parameters(), lr=0.01, weight_decay=1e-4)\n",
    "criterion = nn.CrossEntropyLoss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:41.779740Z",
     "iopub.status.busy": "2023-11-02T08:57:41.779459Z",
     "iopub.status.idle": "2023-11-02T08:57:41.789822Z",
     "shell.execute_reply": "2023-11-02T08:57:41.788827Z",
     "shell.execute_reply.started": "2023-11-02T08:57:41.779717Z"
    }
   },
   "outputs": [],
   "source": [
    "def evaluate_model(model, data_loader):\n",
    "    ground_truth = []\n",
    "    predictions = []\n",
    "\n",
    "    model.eval()\n",
    "    for input_ids, attention_mask, labels in data_loader:\n",
    "        input_ids = input_ids.to(device)\n",
    "        attention_mask = attention_mask.to(device)\n",
    "        labels = labels.to(device)\n",
    "        outputs = model(input_ids=input_ids, attention_mask=attention_mask)\n",
    "        logits = torch.mean(outputs.logits, dim=1)\n",
    "        _, indices = torch.max(logits, 1)\n",
    "        predictions.extend(indices.tolist())\n",
    "        ground_truth.extend(labels.tolist())\n",
    "        del input_ids\n",
    "        del attention_mask\n",
    "        del labels\n",
    "        del outputs\n",
    "        del logits\n",
    "        del indices\n",
    "        free_memory()\n",
    "    accuracy = accuracy_score(ground_truth, predictions)\n",
    "    f1 = f1_score(ground_truth, predictions, average='macro')\n",
    "    del predictions\n",
    "    del ground_truth\n",
    "    free_memory()\n",
    "    return accuracy, f1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:41.791375Z",
     "iopub.status.busy": "2023-11-02T08:57:41.791023Z",
     "iopub.status.idle": "2023-11-02T08:57:41.803406Z",
     "shell.execute_reply": "2023-11-02T08:57:41.802144Z",
     "shell.execute_reply.started": "2023-11-02T08:57:41.791351Z"
    }
   },
   "outputs": [],
   "source": [
    "def train_model(model, train_loader, criterion, optimizer, num_epochs, \n",
    "                step_size=1, gamma=0.5):\n",
    "    scheduler = StepLR(optimizer, step_size=step_size, gamma=gamma)\n",
    "    loss_history = []\n",
    "    train_history = []\n",
    "    \n",
    "    for epoch in range(num_epochs):\n",
    "        model.train()\n",
    "        \n",
    "        loss_accum = 0\n",
    "        correct_samples = 0\n",
    "        total_samples = 0\n",
    "        \n",
    "        for i_step, (input_ids, attention_mask, y) in enumerate(train_loader):\n",
    "            input_ids = input_ids.to(device)\n",
    "            attention_mask = attention_mask.to(device)\n",
    "            y = y.to(device)\n",
    "            outputs = model(input_ids=input_ids, attention_mask=attention_mask)\n",
    "            logits = torch.mean(outputs.logits, dim=1)\n",
    "            optimizer.zero_grad()\n",
    "            loss = criterion(logits, y)\n",
    "            loss.backward()\n",
    "            clip_grad_norm_(model.lm_head.parameters(), 1.0)\n",
    "            optimizer.step()\n",
    "            \n",
    "            _, indices = torch.max(logits, 1)\n",
    "            correct_samples += torch.sum(indices == y)\n",
    "            total_samples += y.shape[0]\n",
    "            loss_accum += loss\n",
    "            \n",
    "            del outputs\n",
    "            del logits\n",
    "            del indices\n",
    "            del input_ids\n",
    "            del attention_mask\n",
    "            del y\n",
    "            free_memory()\n",
    "          \n",
    "        scheduler.step()\n",
    "        ave_loss = loss_accum / i_step\n",
    "        train_accuracy = float(correct_samples) / total_samples\n",
    "\n",
    "        loss_history.append(float(ave_loss))\n",
    "        train_history.append(train_accuracy)\n",
    "        \n",
    "        free_memory()\n",
    "\n",
    "        print(\"Average loss: %f, Train accuracy: %f\" % (ave_loss, train_accuracy))\n",
    "        \n",
    "    return loss_history, train_history"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T08:57:41.805120Z",
     "iopub.status.busy": "2023-11-02T08:57:41.804682Z",
     "iopub.status.idle": "2023-11-02T11:07:36.899148Z",
     "shell.execute_reply": "2023-11-02T11:07:36.898213Z",
     "shell.execute_reply.started": "2023-11-02T08:57:41.805094Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Average loss: 0.830991, Train accuracy: 0.660145\n",
      "Average loss: 0.665423, Train accuracy: 0.711014\n",
      "Average loss: 0.601056, Train accuracy: 0.732964\n",
      "Average loss: 0.569585, Train accuracy: 0.750525\n",
      "Average loss: 0.554496, Train accuracy: 0.759401\n",
      "Average loss: 0.540601, Train accuracy: 0.767799\n",
      "Average loss: 0.537733, Train accuracy: 0.766368\n",
      "Average loss: 0.535967, Train accuracy: 0.767131\n",
      "Average loss: 0.532242, Train accuracy: 0.772571\n",
      "Average loss: 0.531338, Train accuracy: 0.767704\n",
      "Average loss: 0.530329, Train accuracy: 0.769422\n",
      "Average loss: 0.533322, Train accuracy: 0.772094\n",
      "Average loss: 0.530567, Train accuracy: 0.770376\n",
      "Average loss: 0.532977, Train accuracy: 0.769517\n",
      "Average loss: 0.532478, Train accuracy: 0.770662\n"
     ]
    }
   ],
   "source": [
    "loss_history, train_history = train_model(gpt, \n",
    "                                          train_loader, \n",
    "                                          criterion, \n",
    "                                          optimizer, num_epochs)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T11:07:36.902335Z",
     "iopub.status.busy": "2023-11-02T11:07:36.901967Z",
     "iopub.status.idle": "2023-11-02T11:07:37.119978Z",
     "shell.execute_reply": "2023-11-02T11:07:37.118949Z",
     "shell.execute_reply.started": "2023-11-02T11:07:36.902300Z"
    }
   },
   "outputs": [],
   "source": [
    "free_memory()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T11:07:37.121390Z",
     "iopub.status.busy": "2023-11-02T11:07:37.121107Z",
     "iopub.status.idle": "2023-11-02T11:07:37.415482Z",
     "shell.execute_reply": "2023-11-02T11:07:37.414534Z",
     "shell.execute_reply.started": "2023-11-02T11:07:37.121366Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiwAAAGzCAYAAAAMr0ziAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAABb30lEQVR4nO3deXwU9f3H8dfuZo8kJAECuSAQQAj3IQhFPLAi8fghaKtoVQ6FqsV6YKmgAp5Qz1IVxQMQr4patbQiighWFEFBvIBwX0JCIJA72WR3fn9sskkghCQkmU3yfj4e88js7ByfWWP2zXe+8x2LYRgGIiIiIgHManYBIiIiIqeiwCIiIiIBT4FFREREAp4Ci4iIiAQ8BRYREREJeAosIiIiEvAUWERERCTgKbCIiIhIwFNgERERkYCnwCIidS4hIYFx48aZXYaINGAKLCJSba+++ioWi4XvvvuuwveHDh1Kz549T+sYS5cu5YEHHjitfYhI46HAIiJ1Ljk5mZdffrla2yxdupQHH3ywjioSkYZGgUVE6pzT6cRut5tdBl6vl/z8fLPLEJEaUGARkTp3fB+WwsJCHnzwQTp37ozL5SIyMpJzzjmH5cuXAzBu3Djmzp0LgMVi8U8lcnJyuPvuu4mPj8fpdJKYmMiTTz7J8Q+ft1gs3Hbbbbz55pv06NEDp9PJxx9/TEJCAiNHjjyhzvz8fCIiIrj55pvr4FMQkdMRZHYBItJwZWRkcPjw4ROWFxYWVrrdAw88wOzZs5kwYQIDBw4kMzOT7777jg0bNnDRRRdx8803c+DAAZYvX87rr79eblvDMLj88stZuXIlN910E3379uWTTz5hypQp/Prrr/z9738vt/7nn3/OO++8w2233UarVq3o0KED119/PY8//jjp6em0bNnSv+5//vMfMjMzuf7660/jUxGROmGIiFTTwoULDaDSqUePHv7127dvb4wdO9b/uk+fPsZll11W6TEmTZpkVPQn6sMPPzQA45FHHim3/Pe//71hsViM7du3+5cBhtVqNX755Zdy6yYnJxuA8cILL5RbfvnllxsJCQmG1+s95WcgIvVLl4REpMbmzp3L8uXLT5h69+5d6XbNmzfnl19+Ydu2bdU+5tKlS7HZbNx+++3llt99990YhsHHH39cbvn5559P9+7dyy3r0qULgwYN4s033/QvS09P5+OPP+a6664rd/lJRAKDLgmJSI0NHDiQAQMGnLC8RYsWFV4qKvHQQw8xcuRIunTpQs+ePbn44ou54YYbThl0APbs2UNcXBxhYWHllnfr1s3/flkdOnSocD9jxozhtttuY8+ePbRv3553332XwsJCbrjhhlPWICL1Ty0sIlLvzjvvPHbs2MGCBQvo2bMnr7zyCmeeeSavvPJKrR8rODi4wuXXXHMNdrvd38ryxhtvMGDAABITE2u9BhE5fQosImKKli1bMn78eP75z3+yb98+evfuXW6guJNdlmnfvj0HDhwgKyur3PItW7b436/q8S+77DLefPNN9uzZw1dffaXWFZEApsAiIvXuyJEj5V43a9aMM844g4KCAv+y0NBQAI4dO1Zu3UsvvRSPx8Nzzz1Xbvnf//53LBYLl1xySZXruOGGG9i0aRNTpkzBZrNxzTXXVPNMRKS+qA+LiNS77t27M3ToUPr370/Lli357rvveO+997jtttv86/Tv3x+A22+/naSkJH+gGDFiBBdccAH33Xcfu3fvpk+fPnz66af8+9//5s4776RTp05VruOyyy4jMjKSd999l0suuYSoqKhaP1cRqR0KLCJS726//XaWLFnCp59+SkFBAe3bt+eRRx5hypQp/nWuvPJK/vznP/P222/zxhtvYBgG11xzDVarlSVLljBjxgwWL17MwoULSUhI4IknnuDuu++uVh0Oh4PRo0fz/PPP63KQSICzGMZxQ0OKiDQhd911F/PnzyclJYWQkBCzyxGRk1AfFhFpsvLz83njjTf43e9+p7AiEuB0SUhEmpxDhw7x2Wef8d5773HkyBHuuOMOs0sSkVNQYBGRJmfTpk1cd911REVF8cwzz9C3b1+zSxKRU1AfFhEREQl46sMiIiIiAU+BRURERAJeo+jD4vV6OXDgAGFhYXrKqoiISANhGAZZWVnExcVhtVbehtIoAsuBAweIj483uwwRERGpgX379tG2bdtK12kUgaXkMfP79u0jPDzc5GpERESkKjIzM4mPj/d/j1emUQSWkstA4eHhCiwiIiINTFW6c6jTrYiIiAQ8BRYREREJeAosIiIiEvAaRR+WqjAMg6KiIjwej9mlSICw2WwEBQXpVngRkQagSQQWt9vNwYMHyc3NNbsUCTAhISHExsbicDjMLkVERCrR6AOL1+tl165d2Gw24uLicDgc+he1YBgGbrebtLQ0du3aRefOnU85aJGIiJin0QcWt9uN1+slPj6ekJAQs8uRABIcHIzdbmfPnj243W5cLpfZJYmIyEk0mX9S6l/PUhH9XoiINAz6ay0iIiIBT4FFREREAp4Ci5zS7t27sVgsbNy48aTrvPrqqzRv3rzeahIRkaZFgSWAjRs3jlGjRpldRpWMHj2arVu3VmldhRsREamuRn+X0Oko8no5ku2msMhL25a6w6gywcHBBAcH1+sxPR4PFotFHWdFRJqAJvmX3jAMct1Fp5zy3B72HMnhQEYemXnuKm1zqskwjFo7jy+++IKBAwfidDqJjY1l6tSpFBUV+d9/77336NWrF8HBwURGRjJs2DBycnIAWLVqFQMHDiQ0NJTmzZszZMgQ9uzZU+nxdu7cyQUXXEBISAh9+vRhzZo1/veObzX54YcfuOCCCwgLCyM8PJz+/fvz3XffsWrVKsaPH09GRgYWiwWLxcIDDzwAwNGjRxkzZgwtWrQgJCSESy65hG3btp1wjCVLltC9e3ecTierV6/GbreTkpJSrtY777yTc889t6YfrYiIBJgm2cKSV+ih+4xPTDn2poeSCHGc/sf+66+/cumllzJu3Dhee+01tmzZwsSJE3G5XDzwwAMcPHiQa6+9lscff5wrrriCrKwsvvzyS/8jCkaNGsXEiRP55z//idvtZt26daccUO++++7jySefpHPnztx3331ce+21bN++naCgE8/nuuuuo1+/frzwwgvYbDY2btyI3W7n7LPPZs6cOcyYMYPk5GQAmjVrBvgugW3bto0lS5YQHh7OPffcw6WXXsqmTZuw2+0A5Obm8thjj/HKK68QGRlJfHw8HTt25PXXX2fKlCkAFBYW8uabb/L444+f9ucsIiKBoUkGlsbg+eefJz4+nueeew6LxULXrl05cOAA99xzDzNmzODgwYMUFRVx5ZVX0r59ewB69eoFQHp6OhkZGfzf//0fnTp1AqBbt26nPOZf/vIXLrvsMgAefPBBevTowfbt2+natesJ6+7du5cpU6b43+vcubP/vYiICCwWCzExMf5lJUHlq6++4uyzzwbgzTffJD4+ng8//JCrrroK8IWR559/nj59+vi3vemmm1i4cKE/sPznP/8hPz+fq6++uoqfpoiIBLomGViC7TY2PZRUpXVTMwpIy86nRYiDNi1Ov49GsN122vsA2Lx5M4MHDy7XKjJkyBCys7PZv38/ffr04cILL6RXr14kJSUxfPhwfv/739OiRQtatmzJuHHjSEpK4qKLLmLYsGFcffXVxMbGVnrM3r17++dL1j106FCFgWXy5MlMmDCB119/nWHDhnHVVVf5w9HJzicoKIhBgwb5l0VGRpKYmMjmzZv9yxwOR7k6wNcyc//99/PNN9/wm9/8hldffZWrr76a0NDQSs9HREQajibZh8VisRDiCKrS1CLUjstuq9Y2lU319Rwjm83G8uXL+fjjj+nevTvPPvssiYmJ7Nq1C4CFCxeyZs0azj77bBYvXkyXLl345ptvKt1nyWUZwH8eXq+3wnUfeOABfvnlFy677DI+//xzunfvzgcffHDa5xUcHHzCZxgVFcWIESNYuHAhqampfPzxx9x4442nfSwREQkcTTKwVIeruEUkv9BTqx1mT1e3bt1Ys2ZNuZq++uorwsLCaNu2LeALFUOGDOHBBx/k+++/x+FwlAsN/fr1Y9q0aXz99df07NmTt956q1Zr7NKlC3fddReffvopV155JQsXLgR8rSQej+eE8ykqKmLt2rX+ZUeOHCE5OZnu3buf8lgTJkxg8eLFvPTSS3Tq1IkhQ4bU6rmIiIi5FFhOwRFkxWKx4DUMCj0VtybUpYyMDDZu3Fhu2rdvH3/605/Yt28ff/7zn9myZQv//ve/mTlzJpMnT8ZqtbJ27VpmzZrFd999x969e3n//fdJS0ujW7du7Nq1i2nTprFmzRr27NnDp59+yrZt26rUj6Uq8vLyuO2221i1ahV79uzhq6++4ttvv/XvPyEhgezsbFasWMHhw4fJzc2lc+fOjBw5kokTJ7J69Wp++OEHrr/+etq0acPIkSNPecykpCTCw8N55JFHGD9+fK2ch4iIBBCjEcjIyDAAIyMj44T38vLyjE2bNhl5eXk13n9ySqbxw76jRkau+3TKrLaxY8cawAnTTTfdZBiGYaxatco466yzDIfDYcTExBj33HOPUVhYaBiGYWzatMlISkoyWrdubTidTqNLly7Gs88+axiGYaSkpBijRo0yYmNjDYfDYbRv396YMWOG4fF4Kqxj165dBmB8//33/mVHjx41AGPlypWGYRjGwoULjYiICMMwDKOgoMC45pprjPj4eMPhcBhxcXHGbbfdVu6/wS233GJERkYagDFz5kzDMAwjPT3duOGGG4yIiAgjODjYSEpKMrZu3erfpuwxKjJ9+nTDZrMZBw4cqPJnXBu/HyIiUjOVfX8fz2IYAXSdo4YyMzOJiIggIyOD8PDwcu/l5+eza9cuOnTogMvlqtH+96bncizXTUy4i6jwmu1D6t5NN91EWloaS5YsqfI2tfH7ISIiNVPZ9/fxmuRdQtXlCvJdOcsvqv9LQnJqGRkZ/PTTT7z11lvVCisiItJwKLBUQdmOtxJ4Ro4cybp167jlllu46KKLzC5HRETqgAJLFbjsvhaWgiIvXsPAWk+3JkvVrFq1yuwSRESkjukuoSqw26xYLRYMw8Cty0IiIiL1ToGlCiwWiy4LiYiImEiBpYpKLgvlF6qFRUREpL4psFSRWlhERETMo8BSRaW3NiuwiIiI1DcFlioqaWFxF3nxeBv8WHsiIiINigJLFQXZrARZi29vbsCXhRISEpgzZ06d7mP37t1YLBY2btx4WscREREpocBSDf6Ot/VwWchisVQ6PfDAAzXa77fffssf//jH2i32OPHx8Rw8eJCePXuecl2FGxERqQoNHFcNLruN7IKierlT6ODBg/75xYsXM2PGDJKTk/3LmjVr5p83DAOPx0NQ0Kn/c7Zu3bp2C62AzWYjJiamzo9zvMLCQux2e70fV0RE6l7TbGExDHDnVHtyGflYCnMpyM2q0fa4c3zHroKYmBj/FBERgcVi8b/esmULYWFhfPzxx/Tv3x+n08nq1avZsWMHI0eOJDo6mmbNmnHWWWfx2Wefldvv8ZdzLBYLr7zyCldccQUhISF07ty5Ss/jyc3N5cYbbyQsLIx27drx0ksv+d87vtXk6NGjXHfddbRu3Zrg4GA6d+7MwoULAejQoQMA/fr1w2KxMHToUAC8Xi8PPfQQbdu2xel00rdvX5YtW3bCMRYvXsz555+Py+XipZdeIjw8nPfee69crR9++CGhoaFkZWVV6bMXEZHA0zRbWApzYVZctTdrWTydlnsPgCP0dPcCwNSpU3nyySfp2LEjLVq0YN++fVx66aU8+uijOJ1OXnvtNUaMGEFycjLt2rU76X4efPBBHn/8cZ544gmeffZZrrvuOvbs2UPLlic/26eeeoqHH36Ye++9l/fee49bb72V888/n8TExBPWnT59Ops2beLjjz+mVatWbN++nby8PADWrVvHwIED+eyzz+jRowcOhwOAf/zjHzz11FO8+OKL9OvXjwULFnD55Zfzyy+/0Llz53KfwVNPPUW/fv1wuVz88MMPLFy4kN///vf+dUpeh4WFVfszFhGRwNA0W1gaiYceeoiLLrqITp060bJlS/r06cPNN99Mz5496dy5Mw8//DCdOnU6ZYvJuHHjuPbaaznjjDOYNWsW2dnZrFu3rtJtLr30Uv70pz9xxhlncM8999CqVStWrlxZ4bp79+6lX79+DBgwgISEBIYNG8aIESOA0ktUkZGRxMTE+EPSk08+yT333MM111xDYmIijz32GH379j2hs++dd97JlVdeSYcOHYiNjWXChAl88skn/ktqhw4dYunSpdx4442n/DxFRCRwNc0WFnuIr6WjBpJTs3AXeekQGUIzVw36S9hDanTcigwYMKDc6+zsbB544AE++ugjDh48SFFREXl5eezdu7fS/fTu3ds/HxoaSnh4OIcOHaryNiWXq062za233srvfvc7NmzYwPDhwxk1ahRnn332SfedmZnJgQMHGDJkSLnlQ4YM4Ycffii37PjPYODAgfTo0YNFixYxdepU3njjDdq3b895551X6fmIiEhga5otLBaL77JMDSZncBiGPYR8a3DN9lGLT3oODS1/aekvf/kLH3zwAbNmzeLLL79k48aN9OrVC7fbXel+ju+oarFY8Hor71hcnW0uueQS9uzZw1133cWBAwe48MIL+ctf/lLp/qvq+M8AYMKECbz66quA73LQ+PHjsegJ2yIiDVrTDCynIZCH6P/qq68YN24cV1xxBb169SImJobdu3ebXRbgu/QzduxY3njjDebMmePvpFvSZ8XjKf08w8PDiYuL46uvviq3j6+++oru3buf8ljXX389e/bs4ZlnnmHTpk2MHTu2Fs9ERETM0DQvCZ2GQH4IYufOnXn//fcZMWIEFouF6dOnn7KlpD7MmDGD/v3706NHDwoKCvjvf/9Lt27dAIiKiiI4OJhly5bRtm1bXC4XERERTJkyhZkzZ9KpUyf69u3LwoUL2bhxI2+++eYpj9eiRQuuvPJKpkyZwvDhw2nbtm1dn6KIiNQxtbBUU9kWFqOKtyjXl6effpoWLVpw9tlnM2LECJKSkjjzzDPNLguHw8G0adPo3bs35513HjabjbfffhuAoKAgnnnmGV588UXi4uIYOXIkALfffjuTJ0/m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xuPxEB0dXW55dHQ0W7ZsMakqc3i9Xu68806GDBlCz549zS6n3rz99tts2LCBb7/91uxSTLFz505eeOEFJk+ezL333su3337L7bffjsPhYOzYsWaXV+emTp1KZmYmXbt2xWaz4fF4ePTRR7nuuuvMLs0UKSkpABX+TSx5rynJz8/nnnvu4dprr21ST29+7LHHCAoK4vbbb6/3YyuwyClNmjSJn3/+mdWrV5tdSr3Zt28fd9xxB8uXL8flcpldjim8Xi8DBgxg1qxZAPTr14+ff/6ZefPmNYnA8s477/Dmm2/y1ltv0aNHDzZu3Midd95JXFxckzh/ObnCwkKuvvpqDMPghRdeMLucerN+/Xr+8Y9/sGHDBiwWS70fX5eETqJVq1bYbDZSU1PLLU9NTSUmJsakqurfbbfdxn//+19WrlxJ27ZtzS6n3qxfv55Dhw5x5plnEhQURFBQEF988QXPPPMMQUFBeDwes0usc7GxsXTv3r3csm7durF3716TKqpfU6ZMYerUqVxzzTX06tWLG264gbvuuovZs2ebXZopSv7uNfW/iSVhZc+ePSxfvrxJta58+eWXHDp0iHbt2vn/Lu7Zs4e7776bhISEOj++AstJOBwO+vfvz4oVK/zLvF4vK1asYPDgwSZWVj8Mw+C2227jgw8+4PPPP6dDhw5ml1SvLrzwQn766Sc2btzonwYMGMB1113Hxo0bsdlsZpdY54YMGXLCrexbt26lffv2JlVUv3Jzc7Fay/+JtNlseL1ekyoyV4cOHYiJiSn3NzEzM5O1a9c2ib+JUBpWtm3bxmeffUZkZKTZJdWrG264gR9//LHc38W4uDimTJnCJ598UufH1yWhSkyePJmxY8cyYMAABg4cyJw5c8jJyWH8+PFml1bnJk2axFtvvcW///1vwsLC/NeoIyIiCA4ONrm6uhcWFnZCf53Q0FAiIyObTD+eu+66i7PPPptZs2Zx9dVXs27dOl566SVeeukls0urFyNGjODRRx+lXbt29OjRg++//56nn36aG2+80ezS6kx2djbbt2/3v961axcbN26kZcuWtGvXjjvvvJNHHnmEzp0706FDB6ZPn05cXByjRo0yr+haVNn5x8bG8vvf/54NGzbw3//+F4/H4/+72LJlSxwOh1ll16pT/Q4cH9LsdjsxMTEkJibWfXH1ci9SA/bss88a7dq1MxwOhzFw4EDjm2++MbukegFUOC1cuNDs0kzT1G5rNgzD+M9//mP07NnTcDqdRteuXY2XXnrJ7JLqTWZmpnHHHXcY7dq1M1wul9GxY0fjvvvuMwoKCswurc6sXLmywv/vx44daxiG79bm6dOnG9HR0YbT6TQuvPBCIzk52dyia1Fl579r166T/l1cuXKl2aXXmlP9DhyvPm9rthhGIx62UURERBoF9WERERGRgKfAIiIiIgFPgUVEREQCngKLiIiIBDwFFhEREQl4CiwiIiIS8BRYREREJOApsIiIiEjAU2ARERGRgKfAIiIiIgFPgUVEREQC3v8DI1N2QewDUSYAAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title(\"History\")\n",
    "plt.plot(loss_history, label=\"Loss history\")\n",
    "plt.plot(train_history, label=\"Train history\")\n",
    "plt.legend(loc=\"upper left\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T11:07:37.418499Z",
     "iopub.status.busy": "2023-11-02T11:07:37.418212Z",
     "iopub.status.idle": "2023-11-02T11:07:37.423440Z",
     "shell.execute_reply": "2023-11-02T11:07:37.422602Z",
     "shell.execute_reply.started": "2023-11-02T11:07:37.418476Z"
    }
   },
   "outputs": [],
   "source": [
    "test_loader = DataLoader(test_dataset, batch_size=batch_size)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T11:07:37.424827Z",
     "iopub.status.busy": "2023-11-02T11:07:37.424537Z",
     "iopub.status.idle": "2023-11-02T11:11:06.470778Z",
     "shell.execute_reply": "2023-11-02T11:11:06.469894Z",
     "shell.execute_reply.started": "2023-11-02T11:07:37.424798Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test accuracy is 0.7293893129770992\n",
      "Test f1 score is 0.723349162165072\n"
     ]
    }
   ],
   "source": [
    "accuracy, f1 = evaluate_model(gpt, test_loader)\n",
    "print(f\"Test accuracy is {accuracy}\")\n",
    "print(f\"Test f1 score is {f1}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-11-02T11:11:06.472294Z",
     "iopub.status.busy": "2023-11-02T11:11:06.472002Z",
     "iopub.status.idle": "2023-11-02T11:11:08.461409Z",
     "shell.execute_reply": "2023-11-02T11:11:08.460627Z",
     "shell.execute_reply.started": "2023-11-02T11:11:06.472269Z"
    }
   },
   "outputs": [],
   "source": [
    "torch.save(gpt, 'st_sberbank-gpt-sentiment-classifier_medium.pth')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
